#include "stdafx.h"
#include "Camshift.h"


Camshift::Camshift()
{
	//cvNamedWindow("RGB", 1);
}


Camshift::~Camshift()
{
}

void Camshift::Init(uint8_t* data, int size, int width, int height, int selectX, int selectY,
	int selectWidth, int selectHeight, OnTrackResultData trackResultData)
{
	m_onTrackResultData = trackResultData;
	Mat image;
	Mat hsv, hue, mask;
	int hsize = 16;
	float hranges[] = { 0,180 };
	const float* phranges = hranges;

	if (image.empty())
	{
		image.create(cv::Size(width, height), CV_8UC3);
	}
	memcpy(image.data, data, size);

	selection = Rect(selectX, selectY, selectWidth, selectHeight);

	cvtColor(image, hsv, COLOR_BGR2HSV);
	int _vmin = vmin, _vmax = vmax;
	inRange(hsv, Scalar(0, smin, MIN(_vmin, _vmax)), Scalar(180, 256, MAX(_vmin, _vmax)), mask);
	int ch[] = { 0, 0 };
	hue.create(hsv.size(), hsv.depth());
	mixChannels(&hsv, 1, &hue, 1, ch, 1);
	Mat roi(hue, selection), maskroi(mask, selection);
	calcHist(&roi, 1, 0, maskroi, hist, 1, &hsize, &phranges);
	normalize(hist, hist, 0, 255, NORM_MINMAX);

	trackWindow = selection;
}

void Camshift::TrackTarget(uint8_t* data, int size, int width, int height)
{
	Mat image;
	Mat hsv, hue, mask, backproj;
	float hranges[] = { 0,180 };
	const float* phranges = hranges;

	if (image.empty())
	{
		image.create(cv::Size(width, height), CV_8UC3);
	}
	memcpy(image.data, data, size);

	cvtColor(image, hsv, COLOR_BGR2HSV);

	int _vmin = vmin, _vmax = vmax;

	inRange(hsv, Scalar(0, smin, MIN(_vmin, _vmax)), Scalar(180, 256, MAX(_vmin, _vmax)), mask);
	int ch[] = { 0, 0 };
	hue.create(hsv.size(), hsv.depth());
	mixChannels(&hsv, 1, &hue, 1, ch, 1);

	calcBackProject(&hue, 1, 0, hist, backproj, &phranges);
	backproj &= mask;
	RotatedRect trackBox = CamShift(backproj, trackWindow,
		TermCriteria(TermCriteria::EPS | TermCriteria::COUNT, 10, 1));
	if (trackWindow.area() <= 1)
	{
		int cols = backproj.cols, rows = backproj.rows, r = (MIN(cols, rows) + 5) / 6;
		trackWindow = Rect(trackWindow.x - r, trackWindow.y - r,
			trackWindow.x + r, trackWindow.y + r) &
			Rect(0, 0, cols, rows);
	}

	if (backprojMode)
	{
		cvtColor(backproj, image, COLOR_GRAY2BGR);
	}
	if (trackBox.size.width < 5)
	{
		if (m_onTrackResultData != NULL)
		{
			m_onTrackResultData(image.data, 0, image.cols, image.rows, image.step, -1, -1, -1, -1);
		}
	}
	else
	{
		ellipse(image, trackBox, Scalar(0, 0, 255), 3, LINE_AA);
		if (m_onTrackResultData != NULL)
		{
			m_onTrackResultData(image.data, 0, image.cols, image.rows, image.step, trackBox.center.x, trackBox.center.y, trackBox.size.width, trackBox.size.height);
		}
	}
	//rectangle(image, point1, point2, Scalar(0, 0, 255), 3, LINE_AA);
	//int len = strlen((char*)image.data);
	//imshow("RGB", image);
}
